﻿using MP_Game.Protos.V1;
using MP_Network.Ctrls;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace MP_Network
{
    public class NetServer
    {
        private Socket _socket;
        private Dictionary<CmdId, IContainer> _cmdDic = new();
        private readonly string _server_name;
        private NetClient _client;

        public NetServer(string server_name, NetClient client)
        {
            this._server_name = server_name;
            this._client = client;

            ServerAuthCtrl authCtrl = new();
            RegistCommand(CmdId.CmdServerAuth, authCtrl);
            HealthCtrl healthCtrl = new();
            RegistCommand(CmdId.CmdPingReq, healthCtrl);
        }

        public void StartServer(string ip, int port)
        {
            // 1. 创建socket
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            // 2. 设置ip和端口
            EndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port);

            // 3. 绑定ip和端口
            _socket.Bind(endPoint);
            LogMsg.Info($"服务器 {_server_name} 开启成功：{endPoint.ToString()}");

            // 4. 设置最大连接数
            _socket.Listen(10000);

            // 5. 开始接受客户端连接
            Thread listenThread = new Thread(ListenConnectSocket);
            listenThread.IsBackground = true;
            listenThread.Start();
        }

        private void ListenConnectSocket()
        {
            _socket.BeginAccept(ClientConnectCB, null);
        }

        private void ClientConnectCB(IAsyncResult ar)
        {
            try
            {
                // 连接的socket
                Socket clientSocket = _socket.EndAccept(ar);
                LogMsg.Info($"客户端::{clientSocket.RemoteEndPoint} 连接成功...");

                // 开始接受客户端数据，建立与该客户端通信的通道
                Session session = new Session(_cmdDic, clientSocket);
                session.ReceiveData();

                //Session session = new Session(_cmdDic, _client);
                //session.ReceiveData(clientSocket);

                // 继续处理下一个客户端连接请求
                ListenConnectSocket();
            }
            catch (Exception ex)
            {
                LogMsg.Error("NetServer::ClientConnectCB::" + ex.Message);
            }
        }

        /// <summary>
        /// 注册指令
        /// </summary>
        /// <param name="cmd"></param>
        /// <param name="container"></param>
        public void RegistCommand(CmdId cmd, IContainer container)
        {
            _cmdDic.Add(cmd, container);
        }
    }
}
